package com.ken.common.web.exception;

import com.ken.common.core.result.Codes;
import com.ken.common.core.result.R;
import com.ken.common.core.utils.RUtils;
import com.ken.common.web.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 全局异常处理 - 处理基于Controller抛出的异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalException {

    /**
     * 参数校验统一异常处理
     * @return
     */
    @ExceptionHandler(BindException.class)
    public R bindExceptionHandler(BindException e){
        //获得绑定的返回对象
        BindingResult bindingResult = e.getBindingResult();
        //获得校验未通过的所有提示
        Set<String> errorSet = bindingResult.getAllErrors().stream()
                .map(objectError -> objectError.getDefaultMessage())
                .collect(Collectors.toSet());

        return RUtils.createFail(Codes.PARAMENT_ERROR, errorSet);
    }

    /**
     * Spring提供的断言异常处理器
     * @return
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public R illegalArgumentExceptionHandler(IllegalArgumentException e){
        log.error("[Service-Exception] - 捕获到业务异常信息！", e);
        return RUtils.createFail(Codes.SERVER_EXCEPTION.code, e.getMessage());
    }

    /**
     * 业务异常的处理
     * @param e
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    public R serviceExceptionHandler(ServiceException e){
        log.error("[Service-Exception] - 捕获到业务异常信息！", e);
        return RUtils.createFail(e.getCode(), e.getMsg());
    }

    /**
     * 默认异常处理
     * @return
     */
    @ExceptionHandler
    public R globalExceptionHandler(Throwable t){
        log.error("[Global-Exception] - 捕获到全局异常信息！");
        //获取当前请求的url
        HttpServletRequest request = HttpUtils.getRequest();
        String url = request.getRequestURL().toString();
        log.error("[Global-Exception] - 请求的url - {}", url);
        log.error("[Global-Exception] - 异常信息", t);

        return RUtils.createFail(Codes.SERVER_EXCEPTION);
    }
}
